//
// Difficulty evaluation functions
//   Author : Alois Jobard
//

#include "global.h"


// difficulty function for 1 node
float getdiff(igraph_t graph, igraph_integer_t node){
  roominfo *ri;
  
  ri = get_roominfo(&graph, node);
  return ri->enemy_diff + ri->activator_diff+1;
  
}

// difficulty evaluator 1
// the difficulty of a dungeon is the sum of the difficulties of its rooms
float evaldiff1(igraph_t graph){
  float result = 0;
  igraph_vit_t iterator;

  igraph_vs_t vs;
  igraph_vs_all(&vs);

  igraph_vit_create(&graph, vs, &iterator);

  while(!IGRAPH_VIT_END(iterator)){
    result += getdiff(graph, IGRAPH_VIT_GET(iterator));
    IGRAPH_VIT_NEXT(iterator);
  }
  igraph_vit_destroy(&iterator);
  return result;
}

// difficulty evaluator 2
// the difficulty of a dungeon is the sum of the difficulties of its rooms
// with a factor measuring the connectivity of the dungeon
float evaldiff2(igraph_t graph){
  float result = 0;

  int n;
  igraph_vector_t res;
  igraph_vector_init(&res, 1);

  igraph_vit_t iterator;
  igraph_vs_t vs;

  igraph_vit_create(&graph, igraph_vss_all(), &iterator);
  while(!IGRAPH_VIT_END(iterator)){
    igraph_integer_t node =  IGRAPH_VIT_GET(iterator); 
    igraph_vs_1(&vs, node);
    
    igraph_neighborhood_size(&graph, &res, vs, 1, IGRAPH_ALL);
    n = igraph_vector_e(&res, 0)-1;
    result += getdiff(graph, node)*n;
    IGRAPH_VIT_NEXT(iterator);
  }
  igraph_vit_destroy(&iterator);
  return  result / sizeevaluator3(graph);
}


// difficulty evaluator 3
// the difficulty of a dungeon is the average of the difficulty of every rooms
// and the difficulty of the shortest's path rooms
float evaldiff3(igraph_t graph, int start, igraph_vector_t end){
  float result=0;
  int i;
  igraph_vector_ptr_t res;
  igraph_vector_ptr_init(&res, igraph_vector_size(&end));

  igraph_vector_t path;
  igraph_vector_init(&path, igraph_vector_size(&end));

  for (i = 0; i < igraph_vector_size(&end); i++) {
	  igraph_vector_ptr_set(&res, i, &path);
  }

  igraph_vs_t to;
  igraph_vs_vector(&to, &end);

  igraph_vs_t temp;

  igraph_vit_t iterator;
  
  igraph_get_shortest_paths(&graph, &res, start, to, IGRAPH_ALL);
  
  for(i = 0; i<igraph_vector_ptr_size(&res); i++){
 
    igraph_vs_vector(&temp, igraph_vector_ptr_e(&res,i));

    igraph_vit_create(&graph, temp, &iterator);
    while(!IGRAPH_VIT_END(iterator)){
      result += getdiff(graph, IGRAPH_VIT_GET(iterator));
      IGRAPH_VIT_NEXT(iterator);
    }
    igraph_vit_destroy(&iterator);
  }
  result = result / igraph_vector_ptr_size(&res);
  result = (result + evaldiff1(graph))/2;

  igraph_vector_ptr_destroy(&res);
  igraph_vector_destroy(&path);
  igraph_vs_destroy(&to);
  return result;
}

float evaldiff4(igraph_t graph, int start, igraph_vector_t end){
  float result =0;
  float pathdiff=0;
  int i;
  igraph_vector_ptr_t res;
  igraph_vector_ptr_init(&res, igraph_vector_size(&end));

  igraph_vector_t path;
  igraph_vector_init(&path, igraph_vector_size(&end));

  for (i=0; i< igraph_vector_size(&end); i++) {
    igraph_vector_ptr_set(&res, i, &path);
  }
 
  igraph_vs_t to;
  igraph_vs_vector(&to, &end);

  igraph_vs_t temp;

  igraph_vit_t iterator;
  
  igraph_get_shortest_paths(&graph, &res, start, to, IGRAPH_ALL);
  
  for(i = 0; i<igraph_vector_ptr_size(&res); i++){
 
    igraph_vs_vector(&temp,igraph_vector_ptr_e(&res,i));
    igraph_vit_create(&graph, temp, &iterator);
    
    while(!IGRAPH_VIT_END(iterator)){
      pathdiff += getdiff(graph, IGRAPH_VIT_GET(iterator));
      IGRAPH_VIT_NEXT(iterator);
    }
    result+=pathdiff /igraph_vector_size((igraph_vector_t *) igraph_vector_ptr_e(&res,i));
    pathdiff =0;
    igraph_vit_destroy(&iterator);
  }
  result = result / igraph_vector_ptr_size(&res);
  result = (result + evaldiff1(graph)/sizeevaluator1(graph))/2;

  igraph_vector_ptr_destroy(&res);
  igraph_vs_destroy(&to);
  igraph_vector_destroy(&path);
  return result;
}

